/*
 * Copyright (C) National Biorepository Project, KFSHRC, 2003
 * Created on Aug 24, 2003 by aaa
 *
 */
package sa.edu.kfshrc.nb.server.database;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author aaa
 * Created on Aug 24, 2003 at 9:05:38 PM.
 *
 * Force all primary keys to have the same form.
 */
public class PrimaryKey implements Serializable
{
	// ----- RESERVED KEYS ----------------------------------------------------
	// These are used in tables that have *foreign* keys. They can be useful
	// in many different contexts. DO NOT CHANGE THEIR VALUES WITHOUT CHANGING
	// THE VALUES WHEN CREATING THE DATABASE (SEE THE CREATEDATABASE.SQL SCRIPT).
	// One key assumption behind this is that all primary keys in the database
	// start at some number HIGHER than the biggest reserved key here (again,
	// see the createDatabase.sql script).
	private static final long KEY_UNINITIALIZED = 1;
	private static final long KEY_MATCHES_ALL = 2;
	private static final long KEY_DEFAULT_VALUES = 3;
	private static final long KEY_HIGHEST_RESERVED = 999;

	// Matching primary key objects for external use
	public static final PrimaryKey UNINITIALIZED = new PrimaryKey(PrimaryKey.KEY_UNINITIALIZED);
	public static final PrimaryKey MATCHES_ALL = new PrimaryKey(PrimaryKey.KEY_MATCHES_ALL);
	public static final PrimaryKey DEFAULT_VALUES = new PrimaryKey(PrimaryKey.KEY_DEFAULT_VALUES);
	
	// This helper function hides the details of the implementation of primary keys within
	// the database from the rest of the code...
	public static void insertInPreparedStatement(PreparedStatement pstmt, int position, PrimaryKey pk)
		throws SQLException
	{
		pstmt.setLong(position, pk.pkey);
	}

	// Another helper function to retrieve a primary key from a result set and return a
	// PrimaryKey object. Assumes the proper row is being presented.
	public static PrimaryKey getFromResultSet(ResultSet rs, String columnName)
		throws SQLException
	{
		return new PrimaryKey( rs.getLong(columnName) );
	}

	private long pkey;

	public PrimaryKey()
	{
		markAsUninitialized();
	}
	
	public PrimaryKey(String s)
	{
		try
		{
			pkey = Long.parseLong(s);
		}
		catch (Exception e)
		{
			markAsUninitialized();
		}
	}

	// available only to this package (primarily for DatabaseWrapper)
	PrimaryKey(long inPkey)
	{
		pkey = inPkey;
	}
	
	public String toString()
	{
		return Long.toString(pkey);
	}
	
	public int hashCode()
	{
		return (new Long(pkey)).hashCode();
	}
	
	public boolean equals(Object entity)
	{
		return (((PrimaryKey) entity).pkey == pkey);
	}
	
	public void markAsUninitialized()
	{
		pkey = PrimaryKey.KEY_UNINITIALIZED;
	}
	
	public void markAsMatchesAll()
	{
		pkey = PrimaryKey.KEY_MATCHES_ALL;
	}
	
	public boolean isUninitialized()
	{
		return (pkey == PrimaryKey.KEY_UNINITIALIZED);
	}

	public boolean isMatchingAll()
	{
		return (pkey == PrimaryKey.KEY_MATCHES_ALL);
	}
	
	public boolean isDefaultValues()
	{
		return (pkey == PrimaryKey.KEY_DEFAULT_VALUES);
	}
	
	private boolean isReserved()
	{
		return (pkey >= 0 && pkey <= 999);
	}

	public boolean isMatchingOne()
	{
		if (isUninitialized() || isMatchingAll() || isReserved() || isDefaultValues())
			return false;
		return true;
	}
}
